summaryrefslogtreecommitdiff
path: root/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js
diff options
context:
space:
mode:
Diffstat (limited to 'opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js')
-rw-r--r--opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js123
1 files changed, 97 insertions, 26 deletions
diff --git a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js
index 139c2979..a1d6ac7e 100644
--- a/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js
+++ b/opendc-web/opendc-web-ui/src/pages/projects/[project]/topologies/[topology].js
@@ -23,25 +23,37 @@
import { useRouter } from 'next/router'
import { useProject } from '../../../../data/project'
import { useDispatch, useSelector } from 'react-redux'
-import React, { useEffect, useState } from 'react'
+import React, { useEffect, useRef, useState } from 'react'
import { configure, HotKeys } from 'react-hotkeys'
import { KeymapConfiguration } from '../../../../hotkeys'
import Head from 'next/head'
-import MapStage from '../../../../components/app/map/MapStage'
import { openProjectSucceeded } from '../../../../redux/actions/projects'
import { AppPage } from '../../../../components/AppPage'
import {
+ Breadcrumb,
+ BreadcrumbItem,
Bullseye,
+ Divider,
Drawer,
DrawerContent,
DrawerContentBody,
EmptyState,
EmptyStateIcon,
+ PageSection,
+ PageSectionVariants,
Spinner,
+ Tab,
+ TabContent,
+ Tabs,
+ TabTitleText,
+ Text,
+ TextContent,
Title,
} from '@patternfly/react-core'
-import TopologySidebar from '../../../../components/app/sidebars/topology/TopologySidebar'
-import Collapse from '../../../../components/app/map/controls/Collapse'
+import BreadcrumbLink from '../../../../components/util/BreadcrumbLink'
+import MapStage from '../../../../components/topologies/map/MapStage'
+import Collapse from '../../../../components/topologies/map/controls/Collapse'
+import TopologySidebar from '../../../../components/topologies/sidebar/TopologySidebar'
/**
* Page that displays a datacenter topology.
@@ -59,10 +71,29 @@ function Topology() {
}
}, [projectId, topologyId, dispatch])
+ const [activeTab, setActiveTab] = useState('overview')
+ const overviewRef = useRef(null)
+ const floorPlanRef = useRef(null)
+
const topologyIsLoading = useSelector((state) => state.currentTopologyId === '-1')
const interactionLevel = useSelector((state) => state.interactionLevel)
const [isExpanded, setExpanded] = useState(true)
+
+ const breadcrumb = (
+ <Breadcrumb>
+ <BreadcrumbItem to="/projects" component={BreadcrumbLink}>
+ Projects
+ </BreadcrumbItem>
+ <BreadcrumbItem to={`/projects/${projectId}`} component={BreadcrumbLink}>
+ Project details
+ </BreadcrumbItem>
+ <BreadcrumbItem to={`/projects/${projectId}/topologies/${topologyId}`} component={BreadcrumbLink} isActive>
+ Topology
+ </BreadcrumbItem>
+ </Breadcrumb>
+ )
+
const panelContent = <TopologySidebar interactionLevel={interactionLevel} onClose={() => setExpanded(false)} />
// Make sure that holding down a key will generate repeated events
@@ -71,31 +102,71 @@ function Topology() {
})
return (
- <AppPage>
+ <AppPage breadcrumb={breadcrumb}>
<Head>
<title>{project?.name ?? 'Topologies'} - OpenDC</title>
</Head>
- {topologyIsLoading ? (
- <Bullseye>
- <EmptyState>
- <EmptyStateIcon variant="container" component={Spinner} />
- <Title size="lg" headingLevel="h4">
- Loading Topology
- </Title>
- </EmptyState>
- </Bullseye>
- ) : (
- <HotKeys keyMap={KeymapConfiguration} allowChanges={true} className="full-height">
- <Drawer isExpanded={isExpanded}>
- <DrawerContent panelContent={panelContent}>
- <DrawerContentBody>
- <MapStage />
- <Collapse onClick={() => setExpanded(true)} />
- </DrawerContentBody>
- </DrawerContent>
- </Drawer>
- </HotKeys>
- )}
+ <PageSection variant={PageSectionVariants.light}>
+ <TextContent>
+ <Text component="h1">Topology</Text>
+ </TextContent>
+ </PageSection>
+ <PageSection type="none" variant={PageSectionVariants.light} className="pf-c-page__main-tabs" sticky="top">
+ <Divider component="div" />
+ <Tabs
+ activeKey={activeTab}
+ onSelect={(_, tabIndex) => setActiveTab(tabIndex)}
+ className="pf-m-page-insets"
+ >
+ <Tab
+ eventKey="overview"
+ title={<TabTitleText>Overview</TabTitleText>}
+ tabContentId="overview"
+ tabContentRef={overviewRef}
+ />
+ <Tab
+ eventKey="floor-plan"
+ title={<TabTitleText>Floor Plan</TabTitleText>}
+ tabContentId="floor-plan"
+ tabContentRef={floorPlanRef}
+ />
+ </Tabs>
+ </PageSection>
+ <PageSection padding={activeTab === 'floor-plan' && { default: 'noPadding' }} isFilled>
+ <TabContent eventKey="overview" id="overview" ref={overviewRef} aria-label="Overview tab">
+ Test
+ </TabContent>
+ <TabContent
+ eventKey="floor-plan"
+ id="floor-plan"
+ ref={floorPlanRef}
+ aria-label="Floor Plan tab"
+ className="pf-u-h-100"
+ hidden
+ >
+ {topologyIsLoading ? (
+ <Bullseye>
+ <EmptyState>
+ <EmptyStateIcon variant="container" component={Spinner} />
+ <Title size="lg" headingLevel="h4">
+ Loading Topology
+ </Title>
+ </EmptyState>
+ </Bullseye>
+ ) : (
+ <HotKeys keyMap={KeymapConfiguration} allowChanges={true} className="full-height">
+ <Drawer isExpanded={isExpanded}>
+ <DrawerContent panelContent={panelContent}>
+ <DrawerContentBody>
+ <MapStage />
+ <Collapse onClick={() => setExpanded(true)} />
+ </DrawerContentBody>
+ </DrawerContent>
+ </Drawer>
+ </HotKeys>
+ )}
+ </TabContent>
+ </PageSection>
</AppPage>
)
}